
#include "tcx_parser.h"
#include "boost/scoped_ptr.hpp"
#include "gtest/gtest.h"
#include "gps.pb.h"

namespace gps_proto {

class TcxParserTest : public testing::Test {
 protected:
  void SetUp() {
    tcx_parser_.reset(new TcxParser(&gps_proto_));
  }

  GpsProto gps_proto_;
  boost::scoped_ptr<TcxParser> tcx_parser_;
};

TEST_F(TcxParserTest, ParseTcx) {
  tcx_parser_->StartElement("TrainingCenterDatabase", NULL);
  tcx_parser_->EndElement("TrainingCenterDatabase");
}

TEST_F(TcxParserTest, ParseTcxActivities) {
  tcx_parser_->StartElement("TrainingCenterDatabase", NULL);
  tcx_parser_->StartElement("Activities", NULL);
  tcx_parser_->EndElement("Activities");
  tcx_parser_->EndElement("TrainingCenterDatabase");
}

TEST_F(TcxParserTest, ParseTcxTrack) {
  tcx_parser_->StartElement("TrainingCenterDatabase", NULL);
  tcx_parser_->StartElement("Activities", NULL);
  tcx_parser_->StartElement("Activity", NULL);
  tcx_parser_->StartElement("Lap", NULL);
  ASSERT_EQ(1, gps_proto_.track_size());
  tcx_parser_->StartElement("Track", NULL);
  ASSERT_EQ(1, gps_proto_.track(0).segment_size());
  tcx_parser_->EndElement("Track");
  tcx_parser_->EndElement("Lap");
  tcx_parser_->EndElement("Activity");
  tcx_parser_->EndElement("Activities");
  tcx_parser_->EndElement("TrainingCenterDatabase");
}

TEST_F(TcxParserTest, ParseTcxTrackpoint) {
  tcx_parser_->StartElement("TrainingCenterDatabase", NULL);
  tcx_parser_->StartElement("Activities", NULL);
  tcx_parser_->StartElement("Activity", NULL);
  tcx_parser_->StartElement("Lap", NULL);
  ASSERT_EQ(1, gps_proto_.track_size());
  tcx_parser_->StartElement("Track", NULL);
  ASSERT_EQ(1, gps_proto_.track(0).segment_size());
  tcx_parser_->StartElement("Trackpoint", NULL);
  ASSERT_EQ(1, gps_proto_.track(0).segment(0).point_size());
  tcx_parser_->EndElement("Trackpoint");
  tcx_parser_->EndElement("Track");
  tcx_parser_->EndElement("Lap");
  tcx_parser_->EndElement("Activity");
  tcx_parser_->EndElement("Activities");
}

TEST_F(TcxParserTest, ParseTcxTrackpointTime) {
  tcx_parser_->StartElement("TrainingCenterDatabase", NULL);
  tcx_parser_->StartElement("Activities", NULL);
  tcx_parser_->StartElement("Activity", NULL);
  tcx_parser_->StartElement("Lap", NULL);
  ASSERT_EQ(1, gps_proto_.track_size());
  tcx_parser_->StartElement("Track", NULL);
  ASSERT_EQ(1, gps_proto_.track(0).segment_size());
  tcx_parser_->StartElement("Trackpoint", NULL);
  ASSERT_EQ(1, gps_proto_.track(0).segment(0).point_size());
  // <Time>2009-08-27T05:35:25Z</Time>
  tcx_parser_->StartElement("Time", NULL);
  const char* kTime("2009-08-27T05:34:05Z");
  tcx_parser_->CharData(kTime, strlen(kTime));
  tcx_parser_->EndElement("Time");
  ASSERT_EQ(1251351245, gps_proto_.track(0).segment(0).point(0).time());
  tcx_parser_->EndElement("Trackpoint");
  tcx_parser_->EndElement("Track");
  tcx_parser_->EndElement("Log");
  tcx_parser_->EndElement("Activity");
  tcx_parser_->EndElement("Activities");
}

TEST_F(TcxParserTest, ParseTcxTrackpointPosition) {
  tcx_parser_->StartElement("TrainingCenterDatabase", NULL);
  tcx_parser_->StartElement("Activities", NULL);
  tcx_parser_->StartElement("Activity", NULL);
  tcx_parser_->StartElement("Lap", NULL);
  tcx_parser_->StartElement("Track", NULL);
  tcx_parser_->StartElement("Trackpoint", NULL);
  // <Position>
  //   <LatitudeDegrees>47.4599380</LatitudeDegrees>
  //   <LongitudeDegrees>-122.2970404</LongitudeDegrees>
  // </Position>
  tcx_parser_->StartElement("Position", NULL);
  // <LatitudeDegrees>47.4599380</LatitudeDegrees>
  tcx_parser_->StartElement("LatitudeDegrees", NULL);
  const char* kLat("47.4599380");
  tcx_parser_->CharData(kLat, strlen(kLat));
  tcx_parser_->EndElement("LatitudeDegrees");
  ASSERT_EQ(47.4599380, gps_proto_.track(0).segment(0).point(0).lat());
  // <LongitudeDegrees>-122.2970404</LongitudeDegrees>
  tcx_parser_->StartElement("LongitudeDegrees", NULL);
  const char* kLon("-122.2970404");
  tcx_parser_->CharData(kLon, strlen(kLon));
  tcx_parser_->EndElement("LongitudeDegrees");
  ASSERT_EQ(-122.2970404, gps_proto_.track(0).segment(0).point(0).lon());
  tcx_parser_->EndElement("Position");
  tcx_parser_->EndElement("Trackpoint");
  tcx_parser_->EndElement("Track");
  tcx_parser_->EndElement("Lap");
  tcx_parser_->EndElement("Activity");
  tcx_parser_->EndElement("Activities");
}

TEST_F(TcxParserTest, ParseTcxTrackpointAltitude) {
  tcx_parser_->StartElement("TrainingCenterDatabase", NULL);
  tcx_parser_->StartElement("Activities", NULL);
  tcx_parser_->StartElement("Activity", NULL);
  tcx_parser_->StartElement("Lap", NULL);
  tcx_parser_->StartElement("Track", NULL);
  tcx_parser_->StartElement("Trackpoint", NULL);
  // <AltitudeMeters>165.9647217</AltitudeMeters>
  tcx_parser_->StartElement("AltitudeMeters", NULL);
  const char* kAlt("165.9647217");
  tcx_parser_->CharData(kAlt, strlen(kAlt));
  tcx_parser_->EndElement("AltitudeMeters");
  ASSERT_EQ(165.9647217, gps_proto_.track(0).segment(0).point(0).ele());
  tcx_parser_->EndElement("Trackpoint");
  tcx_parser_->EndElement("Track");
  tcx_parser_->EndElement("Lap");
  tcx_parser_->EndElement("Activity");
  tcx_parser_->EndElement("Activities");
}

}  // end namespace gps_proto

int main(int argc, char** argv) {
  testing::InitGoogleTest(&argc, argv);
  return RUN_ALL_TESTS();
}


